import useSyncState from '@/views/hooks/useSyncState';
import AgentServer, { IEvent } from '@/modules/Agent';
import styled from '@emotion/styled';
import { Button, Col, Form, Row, Select, Slider } from 'antd';
import { t } from 'i18next';
import React, { useEffect, useRef, useState } from 'react';
import AudioAnalyser from './libs/AudioAnalyser';
interface MicConfigureProps {
	audioInput: MediaDeviceInfo[];
	mode: 'audio' | 'video' | 'speaker';
	selectKey: string;
	defaultDevice: MediaDeviceInfo | undefined;
	onOk: () => void;
	onCancel: () => void;
	onSelect: (id: string | undefined) => void;
}

interface DeviceInfo {
	value: string;
	label: string;
}

const Submit = styled.div`
	padding-top: 10px;
	text-align: right;
	.ant-btn-default {
		background-color: #fff;
	}
	.ant-btn-primary {
		margin-left: 8px;
	}
`;

const SelectContainer = styled(Select)`
	display: flex;
`;

const MicConfigure = (props: MicConfigureProps) => {
	const { audioInput = [], selectKey = '2', onOk, onCancel, onSelect, defaultDevice } = props;
	const [form] = Form.useForm();
	const [localStream, setLocaStream] = useSyncState<MediaStream | null>(null);
	const audioRef = useRef<HTMLAudioElement | null>(null);
	const audioAnalyserRef = useRef<AudioAnalyser | null>(null);

	const [isTest, setTest] = useState<boolean>(false);

	const [selectedID, setSelectedID] = useSyncState<string>('default');

	const [micDevice, setMicDevice] = useState<DeviceInfo[]>([
		{
			value: 'default',
			label: t('default-device')
		}
	]);

	useEffect(() => {
		const list = audioInput.map(item => ({ value: item.deviceId, label: item.label }));
		setMicDevice([
			{
				value: 'default',
				label: t('default-device')
			},

			...list
		]);
	}, [audioInput]);

	useEffect(() => {
		if (selectKey !== '2') {
			stopLocal();
			setTest(false);
		} else {
			testMic();
		}

		return () => {
			stopLocal();
		};
	}, [selectKey]);

	useEffect(() => {
		form.setFieldValue('inputVol', 0);
		form.setFieldValue('micVol', 80);
		form.setFieldValue('micDeviceID', defaultDevice?.deviceId || 'default');
		setSelectedID(defaultDevice?.deviceId || 'default');
	}, [defaultDevice]);

	const createLocalAudio = async (deviceId?: string) => {
		const constraints = {
			audio: {
				deviceId: deviceId
			},
			video: false
		};
		try {
			const stream = await navigator.mediaDevices.getUserMedia(constraints);
			if (audioRef.current) {
				audioRef.current.srcObject = stream;
				createAnalyser();
			}

			setLocaStream(stream);
			console.log(stream);
		} catch (error) {
			console.log('create local stream failed', error);
		}
	};

	const testMic = async () => {
		try {
			await AgentServer.testMic();
			const list = AgentServer.getAudioDevices().map(item => ({ value: item.deviceId, label: item.label }));
			setMicDevice([
				{
					value: 'default',
					label: t('default-device')
				},
	
				...list
			]);
		} catch (error) {
			console.error('test mic error', error);
		}
	};

	const createAnalyser = () => {
		if (!audioRef.current) return;
		audioAnalyserRef.current = new AudioAnalyser(audioRef.current, true);
		audioAnalyserRef.current.createAnalyser((level: number) => form.setFieldValue('inputVol', level));
	};

	const valueChangeHandler = (values: any) => {
		if (values.micVol !== undefined) {
			if (audioRef.current) {
				audioAnalyserRef.current?.setStreamVol(values.micVol / 100);
			}
		}
	};

	const stopLocal = () => {
		if (localStream()) {
			const traks = localStream()?.getTracks();
			traks?.map(track => track.stop());
			setLocaStream(null);
		}
	};

	const changeHandler = (id: string) => {
		if (isTest) {
			stopLocal();
			createLocalAudio(id);
		}
		setSelectedID(id);
		onSelect(id);
	};

	const micTest = () => {
		if (isTest) {
			stopLocal();
			setTest(false);
		} else {
			createLocalAudio(selectedID());
			setTest(true);
		}
	};

	const ok = () => {
		stopLocal();
		onOk();
	};

	const cancel = () => {
		stopLocal();
		onCancel();
	};

	return (
		<>
			<Form form={form} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} layout="horizontal" style={{ maxWidth: 700 }} onValuesChange={valueChangeHandler}>
				<Row>
					<Col span={18}>
						<Form.Item label={t('mic')} name={'micDeviceID'} labelAlign="left" labelCol={{ span: 6 }}>
							<Select disabled={micDevice.length === 1} defaultValue={form.getFieldValue('micDeviceID') || 'default'} onChange={changeHandler}>
								{micDevice.map(item => (
									<Select.Option key={item.value} value={item.value}>
										{item.label}
									</Select.Option>
								))}
							</Select>
						</Form.Item>
					</Col>
					<Col span={6}>
						<Form.Item>
							<Button type="primary" onClick={micTest} style={{ margin: ' 0 10px', flexGrow: 1 }}>
								{isTest ? t('stop-test') : t('test-mic')}
							</Button>
						</Form.Item>
					</Col>
				</Row>

				<Form.Item label={t('input-level')} name="inputVol" labelAlign="left">
					<Slider defaultValue={0} handleStyle={{ display: 'none' }} />
				</Form.Item>

				<Form.Item label={t('vol')} name="micVol" labelAlign="left">
					<Slider defaultValue={50} />
				</Form.Item>
			</Form>

			<Submit>
				<Button type="default" onClick={cancel}>
					{t('cancel')}
				</Button>
				<Button type="primary" onClick={ok}>
					{t('sure')}
				</Button>
			</Submit>
			<audio autoPlay ref={audioRef} style={{ visibility: 'hidden' }}></audio>
		</>
	);
};

export default MicConfigure;
